package com.opener.web.filter;


import org.apache.commons.io.IOUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * Created by baboy on 02/12/2016.
 */
public class HttpRequestCacheServlet extends HttpServletRequestWrapper {
    private HttpServletRequest request;
    private ByteArrayOutputStream cachedOutputStream;
    /**
     * Constructs a request object wrapping the given request.
     *
     * @param request
     * @throws IllegalArgumentException if the request is null
     */
    public HttpRequestCacheServlet(HttpServletRequest request) {
        super(request);
        this.request = request;
    }

    @Override
    synchronized public ServletInputStream getInputStream()  throws IOException {
        if(cachedOutputStream == null){
            cachedOutputStream = new ByteArrayOutputStream();
            IOUtils.copy(super.getInputStream(), cachedOutputStream);
        }
        ServletInputStream inputStream = new ContentCachedInputStream(cachedOutputStream);
        if (inputStream.markSupported()){
            inputStream.reset();
        }
        return inputStream;
    }

    private class ContentCachedInputStream extends ServletInputStream {
        private ByteArrayInputStream is;
        private boolean isFinished = false;

        public ContentCachedInputStream(ByteArrayOutputStream os) {
            this.is = new ByteArrayInputStream(os.toByteArray());
        }

        public int read() throws IOException {
            int c = is.read();
            if(c == -1){
                isFinished = true;
            }
            return c;
        }
        @Override
        public boolean isFinished() {
            return isFinished;
        }

        @Override
        public boolean isReady() {
            return true;
        }

        @Override
        public void setReadListener(ReadListener readListener) {

        }
        @Override
        public void close() throws IOException{
            is.close();
        }
    }
}
